<template>
  <div class="app-container">
    <div
      class="container"
      ref="containerRef"
      style="width: 100%; height: 500px"
    ></div>
  </div>
</template>

<script setup name="Index">
import G6 from "@antv/g6";
import expand from "@/assets/icons/svg/add.svg";
import collapse from "@/assets/icons/svg/minus.svg";

const { proxy: vm } = getCurrentInstance()



const containerRef = ref(null);
const initG6 = async () => {
  let data = await fetch(
    "https://gw.alipayobjects.com/os/antvdemo/assets/data/algorithm-category.json"
  );
  data = await data.json();

  // 自定义盒子
  G6.registerNode("tree-node", {
    drawShape: function drawShape(cfg, group) {
      // 自定义颜色
      let borderColor = "#0f0";
      let bgColor = "#e6e5e5";
      if(cfg.id == 'Modeling Methods'){
        borderColor = "red"
        bgColor = "yellow"
      }
      // 节点-盒子
      const rect = group.addShape("rect", {
        attrs: {
          fill: bgColor, // 节点背景色
          stroke: borderColor, // 边框颜色
          lineWidth: 1, // 边框粗细
          radius: 4,
          cursor: "pointer",
        },
        name: "cust-rect-shape",
      });
      // 节点-文本
      const text = group.addShape("text", {
        attrs: {
          text: cfg.id,
          // fontFamily: "PingFangSC-Regular",
          fontSize: 12,
          fontWeight: 500,
          textAlign: "center",
          textBaseline: "middle",
          cursor: "pointer",
          fill: "#333",
        },
        name: "cust-text-shape",
      });
      const bbox = text.getBBox(); // 获得文本的盒子 之后的两个节点的xy轴坐标参考bbox
      // 设置 rect方框和text文本 的 x y坐标轴
      rect.attr({
        x: -bbox.width / 2 - 5,
        y: -bbox.height,
        width: bbox.width + 10,
        height: bbox.height + 10,
      });
      // 展开收起-icon
      if (cfg.children && cfg.children.length > 0) {
        let centerX = 0;
        let openIconX = 0
        let openIconY = 0
        if (cfg.id === "Modeling Methods") {
          openIconX = -10
          openIconY = 11
          centerX = cfg.x;
        } else {
          openIconY = -8
          openIconX = cfg.x > centerX ? bbox.width/2 + 6 : -(bbox.width / 2 + 20)
        }
        const collapseIcon = group.addShape("image", {
          attrs: {
            img: cfg.collapsed ? expand : collapse,
            cursor: "pointer",
            width: 14,
            height: 14,
            x: openIconX,
            y: openIconY,
          },
          name: "collapse-icon",
        });
        // 展开和收起icon中间是透明的所以加一个白色图层
        group.addShape("rect", {
          attrs: {
            fill: "#fff",
            width: 14,
            height: 14,
            radius: 7,
            x: openIconX,
            y: openIconY,
          },
          name: "rect-shape2",
        });
        collapseIcon.toFront(); // 让collapseIcon处于白色图层上方
      }
      return rect;
    },
  });
  
  // 实例化
  const graph = new G6.TreeGraph({
    container: containerRef.value,
    width: containerRef.value.offsetWidth,
    height: containerRef.value.offsetHeight,
    fitView: true,
    fitViewPadding: 10,
    fitCenter: true,
    minZoom: 0.1,
    maxZoom: 4,
    modes: {
      default: [
        "drag-canvas",
        "zoom-canvas",
      ],
    },
    defaultNode: {
      type: "tree-node",
      anchorPoints: [
        [0, 0.5],
        [1, 0.5],
      ],
    },
    defaultEdge: {
      type: "cubic-horizontal",
      style: {
        stroke: "#78a8c6",
      },
    },
    layout: {
      type: "mindmap",
      direction: "H",
      // 节点纵向距离
      getVGap: () => {
        return 20;
      },
      // 节点横向距离
      getHGap: () => {
        return 120;
      },
    },
  });
  graph.on('node:mouseenter', (evt) => {
    const { item } = evt;
    graph.setItemState(item, 'active', true);
  });
  graph.on('node:mouseleave', (evt) => {
    const { item } = evt;
    graph.setItemState(item, 'active', false);
  });
  graph.on('node:click', (evt) => {
    const { item, target } = evt;
    graph.setItemState(item, 'selected', true);
    const shape = target;
    const shapeName = shape.cfg.name;
    // 点击收起/展开 icon
    if (shapeName === "collapse-icon") {
      const model = item.getModel();
      const updatedCollapsed = !model.collapsed;
      graph.updateItem(item, { collapsed: updatedCollapsed });
      graph.layout();
      return;
    }
    if(['cust-rect-shape','cust-text-shape'].includes(shapeName)){
      vm.$modal.notifyWarning("点击了公司名字");
    }
  });
  graph.on('canvas:click', (evt) => {
    graph.getNodes().forEach((node) => {
      graph.clearItemStates(node);
    });
  });

  graph.data(data);
  graph.render();
  graph.fitView();
  if (typeof window !== "undefined") {
    window.onresize = () => {
      if (!graph || graph.get("destroyed")) return;
      if (
        !containerRef.value ||
        !containerRef.value.scrollWidth ||
        !containerRef.value.scrollHeight
      )
        return;
      graph.changeSize(
        containerRef.value.scrollWidth,
        containerRef.value.scrollHeight
      );
    };
  }
};
onMounted(() => {
  initG6();
});
</script>

<style scoped lang="scss">
</style>

